package com.wei.web.middleware.httpfilter.registrar.filter.factory;

import com.alibaba.fastjson.JSONObject;
import com.wei.web.middleware.httpfilter.registrar.model.CorsConfigDTO;
import com.wei.web.middleware.httpfilter.registrar.model.FilterConfigDTO;
import com.wei.web.middleware.httpfilter.utils.ZvaCorsRegistry;
import jakarta.servlet.Filter;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistration;

import java.util.HashSet;
import java.util.List;

public class CorsFilterRegistrarFactoryBean extends AbstractFilterRegistrarFactoryBean {

    @Override
    public Filter getFilter() {
        CorsConfigDTO corsConfigDTO = JSONObject.parseObject(JSONObject.toJSONString(filterConfig.getConfig()),
                CorsConfigDTO.class);
        List<CorsConfigDTO.CorsItemConfigDTO> corsConfig = corsConfigDTO.getCorsConfig();
        ZvaCorsRegistry zvaCorsRegistry = new ZvaCorsRegistry();
        for (CorsConfigDTO.CorsItemConfigDTO corsItemConfigDTO : corsConfig) {
            String newPathPattern = expressionHandler.evaluateValue(corsItemConfigDTO.getPathPattern());
            CorsRegistration corsRegistration =
                    zvaCorsRegistry.addMapping(newPathPattern);
            List<String> newAllowedHeaders = expressionHandler.evaluateValue(corsItemConfigDTO.getAllowedHeaders());
            corsRegistration =
                    corsRegistration.allowedHeaders(newAllowedHeaders.toArray(new String[0]));
            List<String> newAllowedMethods = expressionHandler.evaluateValue(corsItemConfigDTO.getAllowedMethods());
            corsRegistration =
                    corsRegistration.allowedMethods(newAllowedMethods.toArray(new String[0]));
            List<String> newAllowedOrigins = expressionHandler.evaluateValue(corsItemConfigDTO.getAllowedOrigins());
            corsRegistration =
                    corsRegistration.allowedOrigins(newAllowedOrigins.toArray(new String[0]));
            if (corsItemConfigDTO.getAllowCredentials() != null) {
                corsRegistration =
                        corsRegistration.allowCredentials(corsItemConfigDTO.getAllowCredentials());
            }
        }

        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.setCorsConfigurations(zvaCorsRegistry.getCorsConfigurations());
        CorsFilter filter = new CorsFilter(configSource);
        return filter;
    }

}
